package com.zhuangjie.redis.config;

import com.zhaungjie.base.utils.json.ObjectMapperBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.data.redis.serializer.SerializationException;
import org.springframework.data.redis.serializer.StringRedisSerializer;

@Configuration
public class RedisConfig {
    @Bean
    public RedisTemplate<String,String> redisTemplate(LettuceConnectionFactory lettuceConnectionFactory)
    {
        RedisTemplate<String,String> redisTemplate = new RedisTemplate<>();
        RedisSerializer<Object> myRedisSerializer = getRedisSerializer();
        redisTemplate.setConnectionFactory(lettuceConnectionFactory);
        //设置key、value序列化方式
        redisTemplate.setKeySerializer(myRedisSerializer);
        redisTemplate.setValueSerializer(myRedisSerializer);
        redisTemplate.setHashKeySerializer(myRedisSerializer);
        redisTemplate.setHashValueSerializer(myRedisSerializer);
        redisTemplate.afterPropertiesSet();
        return redisTemplate;
    }

    private static RedisSerializer<Object> getRedisSerializer() {
        GenericJackson2JsonRedisSerializer genericJackson2JsonRedisSerializer = new GenericJackson2JsonRedisSerializer(ObjectMapperBuilder.ReadyMade.BASE_OM);
        StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();

        RedisSerializer<Object> polymerizedRedisSerializer = new RedisSerializer<Object>() {
            @Override
            public byte[] serialize(Object o) throws SerializationException {
                if (o instanceof String || o instanceof Number || o instanceof Boolean) {
                    return stringRedisSerializer.serialize(String.valueOf(o));
                }
                return genericJackson2JsonRedisSerializer.serialize(o);
            }

            @Override
            public Object deserialize(byte[] bytes) throws SerializationException {
                try{
                    return genericJackson2JsonRedisSerializer.deserialize(bytes);
                }catch (Exception e) {
                    return stringRedisSerializer.deserialize(bytes);
                }
            }
        };
        return polymerizedRedisSerializer;
    }

}